/**
 * Service 层工具函数
 */

import { BusinessError } from './errors'
import { ServiceResult } from './types'

/**
 * 创建成功响应
 */
export function createSuccessResult<T>(data: T, message?: string, code?: number): ServiceResult<T> {
    return {
        success: true,
        data,
        message,
        code
    }
}

/**
 * 创建失败响应
 */
export function createErrorResult(message: string, code?: number): ServiceResult {
    return {
        success: false,
        message,
        code
    }
}

/**
 * 将 BusinessError 转换为 ServiceResult
 */
export function handleServiceError(error: unknown): ServiceResult {
    if (error instanceof BusinessError) {
        return createErrorResult(error.message, error.code)
    }

    if (error instanceof Error) {
        return createErrorResult(error.message, 500)
    }

    return createErrorResult('Unknown error occurred', 500)
}

/**
 * 生成随机数字码
 */
export function generateNumericCode(length: number): string {
    let code = ''
    for (let i = 0; i < length; i++) {
        code += Math.floor(Math.random() * 10)
    }
    return code
}

/**
 * 计算两个时间点之间的分钟差
 */
export function getMinutesDifference(date1: Date, date2: Date): number {
    return Math.floor((date2.getTime() - date1.getTime()) / (1000 * 60))
}

/**
 * 检查日期是否在范围内
 */
export function isDateInRange(date: Date, startDate?: Date, endDate?: Date): boolean {
    if (startDate && date < startDate) return false
    if (endDate && date > endDate) return false
    return true
}

/**
 * 计算百分比
 */
export function calculatePercentage(part: number, total: number): number {
    if (total === 0) return 0
    return Math.round((part / total) * 100 * 100) / 100 // 保留2位小数
}

/**
 * 验证经纬度合法性
 */
export function isValidCoordinates(latitude: number, longitude: number): boolean {
    return latitude >= -90 && latitude <= 90 && longitude >= -180 && longitude <= 180
}

/**
 * 计算两个坐标之间的距离（米）
 * 使用 Haversine 公式
 */
export function calculateDistance(lat1: number, lon1: number, lat2: number, lon2: number): number {
    const R = 6371e3 // 地球半径（米）
    const φ1 = (lat1 * Math.PI) / 180
    const φ2 = (lat2 * Math.PI) / 180
    const Δφ = ((lat2 - lat1) * Math.PI) / 180
    const Δλ = ((lon2 - lon1) * Math.PI) / 180

    const a = Math.sin(Δφ / 2) * Math.sin(Δφ / 2) + Math.cos(φ1) * Math.cos(φ2) * Math.sin(Δλ / 2) * Math.sin(Δλ / 2)
    const c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a))

    return R * c
}

/**
 * 延迟执行（用于测试或限流）
 */
export function delay(ms: number): Promise<void> {
    return new Promise(resolve => setTimeout(resolve, ms))
}

/**
 * 分批处理数组
 */
export async function processBatch<T, R>(
    items: T[],
    batchSize: number,
    processor: (batch: T[]) => Promise<R[]>
): Promise<R[]> {
    const results: R[] = []

    for (let i = 0; i < items.length; i += batchSize) {
        const batch = items.slice(i, i + batchSize)
        const batchResults = await processor(batch)
        results.push(...batchResults)
    }

    return results
}

/**
 * 安全的 JSON 解析
 */
export function safeJsonParse<T>(json: string, defaultValue: T): T {
    try {
        return JSON.parse(json) as T
    } catch {
        return defaultValue
    }
}

/**
 * 格式化日期为 YYYY-MM-DD
 */
export function formatDate(date: Date): string {
    const year = date.getFullYear()
    const month = String(date.getMonth() + 1).padStart(2, '0')
    const day = String(date.getDate()).padStart(2, '0')
    return `${year}-${month}-${day}`
}

/**
 * 格式化日期时间为 YYYY-MM-DD HH:mm:ss
 */
export function formatDateTime(date: Date): string {
    const dateStr = formatDate(date)
    const hours = String(date.getHours()).padStart(2, '0')
    const minutes = String(date.getMinutes()).padStart(2, '0')
    const seconds = String(date.getSeconds()).padStart(2, '0')
    return `${dateStr} ${hours}:${minutes}:${seconds}`
}
